import * as Cesium from 'cesium';
import gsap from 'gsap';

export default class PolylineTrainMaterialProperty {
  constructor(name) {
    this.name = name; // 为了判断两者是否是同一材质的标记

    this.definitionChanged = new Cesium.Event();
    Cesium.Material._materialCache.addMaterial('PolylineTrainMaterial', {
      fabric: {
        type: 'PolylineTrainMaterial',
        uniforms: {
          uTime: 0,
        },
        /**
     * czm_materialInput 可用的参数如下
      positionToEyeEC：视点到物体的眼睛空间位置向量。
      normalEC：眼睛坐标系下的法线向量。
      tangentToEyeMatrix：切线到眼睛的矩阵。
      str：切线空间的s向量。
      normal：切线空间的法线向量。
      tangent：切线空间的切线向量。
      bitangent：切线空间的副切线向量。
      lightDirectionEC：眼睛坐标系下的光源方向向量。
      h：半向量，即视线方向和光线方向的平均值。
      s：投影纹理坐标的s分量。
      t：投影纹理坐标的t分量。

      czm_material 使用gpt搜索查看具体属性: cesium czm_material 包含哪些内容，分别说明
     */
        // 自定义 着色器
        source: `czm_material czm_getMaterial(czm_materialInput materialInput) 
           {
                // 生成默认的材质
                czm_material material = czm_getDefaultMaterial(materialInput);
                // 获取st
                vec2 st = materialInput.st;

                // 获取当前帧数，10秒内变化从0-1
                float time = fract(czm_frameNumber / (60.0 * 10.0));
                time = time * (1.0 + 0.1);

                // 平滑过度函数
                // smoothstep(edge0, edge1, value);
                // 设置材质的透明度
                float alpha = smoothstep(time - 0.1, time, st.s) * step(-time, -st.s);
                material.alpha = alpha;
                material.diffuse = vec3(1.0,0.6,0.6);
                return material;
            }`,
      },
    });
    this.params = {
      uTime: 0,
    };
    // 动态修改参数值
    gsap.to(this.params, {
      uTime: 1,
      duration: 2,
      repeat: -1,
      yoyo: true, // 循环变化
      ease: 'linear',
    });
  }
  getType() {
    return `PolylineTrainMaterial`;
  }
  getValue(time, result) {
    // 方案一: 动态修改 uniforms.uTime 并更新到 着色器 中
    // let t = performance.now() / 1000;
    // t = t % 1;
    // result.uTime = t;

    // 方案二
    result.uTime = this.params.uTime;

    return result; // 返回材质
  }
  equals(other) {
    // 判断两个材质是否相等
    return (
      other instanceof PolylineTrainMaterialProperty && this.name === other.name
    );
  }
}
